package com.apes.importData.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.jpa.repository.CustomRepository;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.JpaUtil;
import com.apes.framework.util.ReflectUtil;
import com.apes.importData.model.ImportControls;
import com.apes.importData.respository.ImportControlsRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName ImportControlsService
 * @Description TODO
 * @Author pengyb
 * @Date 2019/3/23 9:29
 * @Version 1.0
 **/
@Service("importControlsService")
public class ImportControlsService extends DomainService {
    @Autowired
    private ImportControlsRepository importControlsRepository;

    /**
     * 保存/更新
     *
     * @param request
     * @return
     */
    public ImportControls save(SimpleRequest request) {
        ImportControls importControls = request.getO(ImportControls.class);
        return importControlsRepository.saveAndFlush(importControls);

    }

    /**
     * 删除
     *
     * @param request
     * @return
     */
    public String delete(SimpleRequest request) {
        ImportControls importControls = importControlsRepository.findOne(request.get("id").toString());
        importControlsRepository.delete(importControls.getId());
        return "删除成功";
    }

    /**
     * 通用导入
     *
     * @param request
     * @return
     */
    public JSONObject beImport(SimpleRequest request) {
        JSONObject importData = request.get("importData");//Excel信息
        List<Map> data = request.get("data");                     //获取页面标签信息
        JSONObject exclObject = new JSONObject();                  //返回值

        //以headerName为key 存储cellEditor,cellEditorParams,downFormatter,field
        Map<String, Map> header = data.stream().collect(Collectors.toMap(x -> x.get("name").toString(), x -> x));

        //传来的Key 未知，遍历
        importData.forEach((k, v) -> {
            //获得value===Excel内容
            JSONArray excl = (JSONArray) importData.get(k); //excl原值
            JSONArray result = new JSONArray();         //返回值

            //map存放匹配过的数据------
            Map<Object, Object> resultMap = new HashMap();

            JSONArray firstLine = (JSONArray) excl.get(0);      //firstLine==Excel表头
            result.add(firstLine);
            //遍历value===遍历excel每一行
            for (int i = 0; i < excl.size(); i++) {
                if (i == 0) {  //跳过表头
                    continue;
                }
                JSONArray currentLine = (JSONArray) excl.get(i); //获取当前行
                if (currentLine.size() == 0) {
                    continue; //跳过空白行
                }
                for (int j = 0; j < currentLine.size(); j++) {     //遍历每一行内容

                    Object line = currentLine.get(j);//行内容

                    //如果当前单元格内容已经存在于map中，直接拿取
                    if (resultMap.containsKey(firstLine.get(j) + ":" + line)) {  //KEY:Excel列名+单元格内容
                        currentLine.set(j, resultMap.get(firstLine.get(j) + ":" + line));
                        continue;
                    }

                    //获取表头标题对应的field值
                    if (!header.containsKey(firstLine.getString(j))) {
                        throw new RuntimeException(String.format("Excl表头中[%s]在界面中无对照！请检查！", firstLine.getString(j)));
                    }
                    String field = (String) header.get(firstLine.getString(j)).get("field");
                    if (field.equals("operation")) {
                        currentLine.set(j, "");
                        continue; //跳过序号
                    }

                    //获取实体的领域类
                    String domainTypeName = JpaUtil.getAllDomainType().stream()
                            .filter(s -> ReflectUtil.getClass(s).getSimpleName().equalsIgnoreCase(field))
                            .findFirst().orElse(null);

                    if (domainTypeName == null) {                       //获取不到实体的领域类
                        //查询对照表
                        ImportControls importControls = importControlsRepository.findAllByBizField(field);
                        if (importControls != null)
                            domainTypeName = JpaUtil.getDomainClass(importControls.getBusinessType().getId()).getName();
                    }
                    if (domainTypeName != null) {                       //基本数据类型,不做改变；或者未录入对照表
                        CustomRepository repository = JpaUtil.getRepository(domainTypeName);

                        Object value = null;

                        try {
                            Serializable id = JpaUtil.getId(domainTypeName, line.toString());
                            value = repository.findOne(id);
                        } catch (Exception e) {
                        }

                        //检查是否枚举属性
                        if (domainTypeName.equals("com.apes.scm.masterdata.enumeration.model.Enumeration")) {
                            value = repository.findOne(JpaDsl.toCriteriaByEq("description", line, "type.id", field)).orElse(null);
                        }

                        //检查是否当事人角色属性
                        if (value == null && domainTypeName.equals("com.apes.scm.masterdata.party.model.PartyRole")) {
                            try {
                                char[] chars = field.toCharArray();
                                chars[0] = chars[0] ^= 32;
                                value = repository.findOne(JpaDsl.toCriteriaByEq("party.name", line, "role.id", String.valueOf(chars))).orElse(null);
                            } catch (Exception e) {
                                throw new RuntimeException(firstLine.getString(j) + ":" + line + " 在对应表中存在重名或无法根据当前条件获取，导入终止，建议检查此列数据，修改为ID导入。");
                            }

                        }

                        if (value == null) {
                            try {
                                value = repository.findOne(JpaDsl.toCriteriaByEq("name", line)).orElse(null);

                            } catch (Exception e) {
                                throw new RuntimeException(firstLine.getString(j) + ":" + line + " 在对应表中存在重名或无法根据当前条件获取，导入终止，建议检查此列数据，修改为ID导入。");
                            }
                        }

                        if (value == null) {
                            throw new RuntimeException(firstLine.getString(j) + ":" + line + " 命名不规范或者在对照表中不存在，导入终止，建议检查此列记录。");
                        }

                        //有且只有此一行记录,修改Excel内容
                        currentLine.set(j, value);
                        //存入map
                        resultMap.put(firstLine.get(j) + ":" + line, value); //KEY:Excel列名+单元格内容
                    } else { //基本数据类型
                        if (currentLine.get(j) == null) {  // 为空时传回''
                            (currentLine).set(j, "");
                        }
                    }
                }
                result.add(currentLine);
                exclObject.put(k, result);
            }
        });

        return exclObject;
    }

}
